home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / Apple II / Essentials / Technical.Notes / IIGS / TN.IIGS.001 next >
Encoding:
Text File  |  1990-04-03  |  7.3 KB  |  148 lines  |  [TEXT/pdos]

  1. Apple II
  2. Technical Notes
  3. _____________________________________________________________________________
  4.                                                   Developer Technical Support
  5.  
  6. Apple IIGS
  7. #1:    How to Install Custom BRK and /NMI Handlers
  8.  
  9. Revised by:    Jim Mensch & Jim Merritt                         November 1988
  10. Written by:    Jim Merritt                                       October 1986
  11.  
  12. This Technical Note discusses a method to install a custom debugger or 
  13. debugging stub within the Apple IIGS system.
  14. _____________________________________________________________________________
  15.  
  16.  
  17. Introduction
  18.  
  19. This Technical Note discusses a particular method that you may use to install 
  20. a custom debugger or debugging stub within the Apple IIGS system.  The 
  21. strategy and techniques described here should be of special interest to those 
  22. who wish to operate the Apple IIGS as a slave to a debugger that resides on 
  23. another machine.
  24.  
  25. Typically, an interrupt handler should pass control to a debugger or debugging 
  26. stub whenever the processor executes a BRK instruction, or when an interface 
  27. card triggers a non-maskable interrupt (/NMI).  To simplify the design of the 
  28. debugger, the Apple IIGS Monitor should be responsible for the following:
  29.  
  30.   o  saving all machine state information in locations that the 
  31.      debugger can access
  32.   o  setting the machine to a known state
  33.   o  passing control to an arbitrary debugger
  34.   o  restoring the remembered machine state upon regaining control from 
  35.      the debugger
  36.   o  resurrecting the interrupted process
  37.  
  38. The Monitor is designed to provide all of the services above for the BRK 
  39. instruction, but only the third for /NMI interrupts.  In addition, Apple II 
  40. family systems are generally intolerant of /NMI interrupts.  In this Technical 
  41. Note we concentrate on the means by which you can install your own custom BRK 
  42. handler, although we also briefly examine /NMI considerations.
  43.  
  44.  
  45. Dealing With BRK
  46.  
  47. A BRK interrupt handler may reside at any address in memory.  The Monitor 
  48. passes control to your code by executing a JSL instruction; consequently, your 
  49. routine must terminate with an RTL instruction.  To install your BRK handler, 
  50. simply load it into memory, call the Miscellaneous Tool Set GetVector routine 
  51. to fetch the address of the current BRK handler, put that address in a safe 
  52. place, then supply the address of your handler to the Miscellaneous Tool Set 
  53. SetVector routine.  To deactivate your handler, restore the previous handler 
  54. address using SetVector as follows:
  55.  
  56. ;
  57. ;  NOTE: All Listings are in APW assembler format.
  58. ;
  59.  
  60. INSTMYBRK    anop                  ;Example code to install user's BREAK handler.
  61.              PushLong #0           ;Space for function call result.
  62.              PushWord #$1C         ;We want BREAK vector address.
  63.              _GetVector            ;Make the call using standard macro.
  64.  
  65. ;  The stack now holds address of the current break handler.
  66.              PLA                   ;Get and save low word of address...
  67.              STA    SBRKADR
  68.              PLA                   ; ...and now high word.
  69.              STA    SBRKADR+2
  70.              PushWord #$1C         ;We want to change BREAK vector address.
  71.              PushLong #MYHANDLR    ;Address of user's BRK handler.
  72.              _SetVector            ;Make the call using standard macro.
  73.  
  74. ;  Custom handler is in place, now go off and do whatever we like...
  75.  
  76. DEACMYBRK    anop                  ;Example code to deactivate the BRK handler.
  77.              PushWord #$1C         ;We want to change BREAK vector address.
  78.              PushLong SBRKADR      ;The previous BRK handler address.
  79.              _SetVector            ;Make the call using standard macro.
  80.  
  81. Upon entry to your code, the machine will be in eight-bit native mode.  
  82. Specifically, the m and x bits will be set (forcing eight-bit accumulator, 
  83. memory access, and index registers), the processor will be running at the 
  84. normal (1 MHz) speed, all memory shadowing will be enabled, and both the 
  85. direct page and data bank registers will be reset to zero.  The same 
  86. conditions must hold when your BRK handler returns control to the Monitor.  
  87. While your code is active, however, it is free to affect the machine state in 
  88. arbitrary ways, including (but not limited to) widening the registers, 
  89. increasing the clock rate, and disabling shadowing.  Before returning control 
  90. to the Monitor, your break handler must also clear the processor's carry flag, 
  91. as an indication that the BRK was indeed serviced by an external handler.  
  92. (Note:  The default BREAKVECTOR points to a "no-op" handler that simply sets 
  93. the carry flag to indicate that there is no external handler available, and it 
  94. then executes an RTL.)
  95.  
  96. When a BRK occurs, the processor saves the machine's state in the BRK.VAR 
  97. area, and you may obtain this address with the Miscellaneous Tool Set GetAddr 
  98. routine as follows:
  99.  
  100.              PushLong #0           ; space for result
  101.              PushWord #9           ; we want BRK.VAR address
  102.             _GetAddr               ; make the call using standard macro
  103.  
  104. ; The stack now holds the address of the BRK.VAR area, expressed as a long 
  105. word (four bytes).
  106.  
  107.  
  108. Coping With /NMI
  109.  
  110. Handling /NMI interrupts is, by far, a trickier proposition than fielding BRK 
  111. instructions.  For example, the user-definable /NMI jump-vector, /NMI 
  112. ($0003FB), only has room in its three-byte JMP-absolute instruction for a two-
  113. byte address.  Because of this size limitation, at least the "front end" of 
  114. any /NMI handler must reside in bank $00.  In addition, the Monitor does not 
  115. "condition" the system in any way before transferring control through the /NMI 
  116. hook, so the system could be in native mode, emulation mode, or any hybrid 
  117. mode (with any screen condition) upon entry to your handler.  (Note:  Although 
  118. the 65816 processor provides for separate /NMI vector addresses in native and 
  119. emulation modes, the Apple IIGS implementation of these two vectors pass 
  120. control to the same user hook at $0003FB.)  The processor only saves minimal 
  121. machine state information when an /NMI occurs; if the handler needs to 
  122. preserve more than the program counter and status register (which are saved 
  123. automatically), then it must do so explicitly.  Because the 65816 assumes any 
  124. program running in emulation mode has its program bank register in bank zero, 
  125. it will not save the program bank register for any program running in 
  126. emulation mode outside of bank zero.  Code which runs in this manner will 
  127. always crash if it makes any attempt to return from the interrupt.  Finally, 
  128. /NMI interrupts can create havoc with disk access and other aspects of the 
  129. system; consequently, the only way you can safely use /NMI interrupts is as a 
  130. one-way "escape hatch" to emergency debugging code.
  131.  
  132. Here are some ground rules for /NMI interrupt handlers.
  133.  
  134.   o  On entry, store any interesting registers or machine state in RAM 
  135.      space owned by the handler.
  136.   o  Determine whether the processor is in emulation mode or native 
  137.      mode.
  138.   o  Take appropriate action, depending upon the processor mode.
  139.   o  Under no circumstances try to return from the interrupt!  Restart 
  140.      the system instead.
  141.  
  142. To install an /NMI handler, load it into some free RAM in bank $00, put the 
  143. two-byte address currently at location /NMI+1 in a safe place, then replace it 
  144. with the address of your handler.  To deactivate your handler (assuming 
  145. nothing has yet invoked it), simply restore the previous handler address to 
  146. /NMI+1.
  147.  
  148.